﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Win32;
using System.IO;
using System.Xml;

namespace EffiProz.InstallerCustomAction
{
    public class CustomActions
    {     
        private static List<string> InitFrameworks()
        {
            RegistryKey key;
            string frameworkpath;

            List<string> _frameworks = new List<string>();

            using (key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\.NETFramework"))
            {
                frameworkpath = key.GetValue("InstallRoot") as string;
            }

            string[] frameworkfolders = Directory.GetDirectories(frameworkpath);
            foreach (string framework in frameworkfolders)
            {
                if (File.Exists(Path.Combine(framework, "CONFIG\\machine.config")))
                    _frameworks.Add(Path.GetFileName(framework));
            }

            return _frameworks;
        }


        [CustomAction]
        public static ActionResult RegisterAdoProvider(Session session)
        {
            session.Log("Begin RegisterAdoProvider");

           // System.Diagnostics.Debugger.Launch();

            List<string> _frameworks = InitFrameworks();

            for (int n = 0; n < 2; n++)
            {
                foreach (string framework in _frameworks)
                {
                    // Add factory support to the machine.config file.
                    try
                    {
                        string xmlFileName = Environment.ExpandEnvironmentVariables(String.Format("%WinDir%\\Microsoft.NET\\{0}\\{1}\\CONFIG\\machine.config",
                            (n == 0) ? "Framework" : "Framework64", framework));
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.PreserveWhitespace = true;
                        try
                        {
                            xmlDoc.Load(xmlFileName);
                        }
                        catch (Exception e)
                        {
                            session.Log("RegisterAdoProvider machine.config not found :" + e.ToString());
                            continue;
                        }


                        XmlNode xmlNode = xmlDoc.SelectSingleNode("configuration/system.data/DbProviderFactories/add[@invariant=\"System.Data.EffiProz\"]");
                        if (xmlNode == null)
                        {
                            XmlNode xmlConfig = xmlDoc.SelectSingleNode("configuration");
                            if (xmlConfig != null)
                            {
                                XmlNode xmlData = xmlConfig.SelectSingleNode("system.data");
                                if (xmlData == null)
                                {
                                    xmlData = xmlDoc.CreateNode(XmlNodeType.Element, "system.data", "");
                                    xmlConfig.AppendChild(xmlData);
                                }
                                XmlNode xmlParent = xmlData.SelectSingleNode("DbProviderFactories");
                                if (xmlParent == null)
                                {
                                    xmlParent = xmlDoc.CreateNode(XmlNodeType.Element, "DbProviderFactories", "");
                                    xmlData.AppendChild(xmlParent);
                                }

                                xmlNode = xmlDoc.CreateNode(XmlNodeType.Element, "add", "");
                                xmlNode.Attributes.SetNamedItem(xmlDoc.CreateAttribute("name"));
                                xmlNode.Attributes.SetNamedItem(xmlDoc.CreateAttribute("invariant"));
                                xmlNode.Attributes.SetNamedItem(xmlDoc.CreateAttribute("description"));
                                xmlNode.Attributes.SetNamedItem(xmlDoc.CreateAttribute("type"));
                                xmlParent.AppendChild(xmlNode);
                            }
                        }                     

                        xmlNode.Attributes.GetNamedItem("name").Value = "EffiProz Data Provider";
                        xmlNode.Attributes.GetNamedItem("invariant").Value = "System.Data.EffiProz";
                        xmlNode.Attributes.GetNamedItem("description").Value = ".Net Framework Data Provider for EffiProz";
                        xmlNode.Attributes.GetNamedItem("type").Value = "System.Data.EffiProz.EfzFactory, System.Data.EffiProz, Version=0.1.0.1, Culture=neutral, PublicKeyToken=89e74d577370ac3d";

                        xmlDoc.Save(xmlFileName);

                    }
                    catch(Exception e)
                    {
                        session.Log("Error RegisterAdoProvider :"+e.ToString());
                        return ActionResult.Failure;
                    }

                }
            }

            session.Log("End RegisterAdoProvider");
            return ActionResult.Success;
        }


        [CustomAction]
        public static ActionResult UnRegisterAdoProvider(Session session)
        {
            session.Log("Begin UnRegisterAdoProvider");

            List<string> _frameworks = InitFrameworks();


            for (int n = 0; n < 2; n++)
            {
                try
                {
                    foreach (string framework in _frameworks)
                    {
                        // Remove any entries in the machine.config if they're still there
                        string xmlFileName = Environment.ExpandEnvironmentVariables(String.Format("%WinDir%\\Microsoft.NET\\{0}\\{1}\\CONFIG\\machine.config", (n == 0) ? "Framework" : "Framework64", framework));
                        XmlDocument xmlDoc = new XmlDocument();
                        xmlDoc.PreserveWhitespace = true;
                        try
                        {
                            xmlDoc.Load(xmlFileName);
                        }
                        catch (Exception e)
                        {
                            session.Log("UnRegisterAdoProvider machine.config not found :" + e.ToString());
                            continue;
                        }

                        XmlNode xmlNode = xmlDoc.SelectSingleNode("configuration/system.data/DbProviderFactories/add[@invariant=\"System.Data.EffiProz\"]");

                        if (xmlNode != null)
                            xmlNode.ParentNode.RemoveChild(xmlNode);

                        xmlNode = xmlDoc.SelectSingleNode("configuration/system.data/DbProviderFactories/remove[@invariant=\"System.Data.EffiProz\"]");
                        if (xmlNode != null)
                            xmlNode.ParentNode.RemoveChild(xmlNode);

                        xmlDoc.Save(xmlFileName);
                    }
                }
                catch(Exception e)
                {
                    session.Log("Error UnRegisterAdoProvider :" + e.ToString());
                    return ActionResult.Failure;
                }
            }

            session.Log("End UnRegisterAdoProvider");

            return ActionResult.Success;
        }
    }
}
